/*******************************************************************************
 *
 *	:  IO
 *
 *******************************************************************************/
#define PORT_PIN_CTEAT
#include "bsp.h"
#include "bsp_io.h"
#include "iohandle.h"
#include "pincfg.h"
#include "mytype.h"

/*******************************************************************************
 * @brief  ext sim io
 *******************************************************************************/
uint8_t ext_port_out[4][8];
uint8_t ext_port_in[4];

// void bsp_pin_mux_cfg(GPIO_TypeDef *gpio_x, uint32_t pin, gpio_mux_sel_type gpio_mux);

/*******************************************************************************
 * @brief  gpio cfg list
 *******************************************************************************/
static gpio_init_cfg_type gpio_cfg[] = {
	// UART1
	{GPIOA, GPIO_Mode_AF_PP, GPIO_Speed_50MHz, 1, GPIO_Pin_9}, // TX
	{GPIOA, GPIO_Mode_IPU, GPIO_Speed_50MHz, 1, GPIO_Pin_10},  // RX

	// UART7
	{GPIOC, GPIO_Mode_AF_PP, GPIO_Speed_10MHz, 1, GPIO_Pin_2}, // TX
	{GPIOC, GPIO_Mode_IPU, GPIO_Speed_10MHz, 1, GPIO_Pin_3},   // RX

	// UART8
	{GPIOC, GPIO_Mode_AF_PP, GPIO_Speed_10MHz, 1, GPIO_Pin_4}, // TX
	{GPIOC, GPIO_Mode_IPU, GPIO_Speed_10MHz, 1, GPIO_Pin_5},   // RX

	// SPI2
	{GPIOB, GPIO_Mode_Out_PP, GPIO_Speed_50MHz, 1, GPIO_Pin_12}, // CS
	{GPIOB, GPIO_Mode_AF_PP, GPIO_Speed_50MHz, 1, GPIO_Pin_15},	 // MOSI
	{GPIOB, GPIO_Mode_IPU, GPIO_Speed_50MHz, 1, GPIO_Pin_14},	 // MISO
	{GPIOB, GPIO_Mode_AF_PP, GPIO_Speed_50MHz, 1, GPIO_Pin_13},	 // SCK

	// OLED
	{GPIOB, GPIO_Mode_Out_PP, GPIO_Speed_50MHz, 1, GPIO_Pin_0}, // DC
	{GPIOB, GPIO_Mode_Out_PP, GPIO_Speed_50MHz, 1, GPIO_Pin_1}, // RST

	// LED
	{GPIOA, GPIO_Mode_Out_PP, GPIO_Speed_10MHz, 1, GPIO_Pin_0}, //
	{GPIOA, GPIO_Mode_Out_PP, GPIO_Speed_10MHz, 1, GPIO_Pin_1}, //

	// USER KEY
	{GPIOA, GPIO_Mode_IPU, GPIO_Speed_50MHz, 1, GPIO_Pin_14}, //
};

/*******************************************************************************
 * @brief  bsp_gpio_init
 * \param[in] us delay
 * \retval: none
 *******************************************************************************/
void bsp_gpio_init(void)
{
	int index;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

	/*gpio cfg*/
	for (index = 0; index < sizeof(gpio_cfg) / sizeof(gpio_init_cfg_type); index++)
	{
		GPIO_InitTypeDef GPIO_InitStruct;

		GPIO_InitStruct.GPIO_Pin = gpio_cfg[index].pin;
		GPIO_InitStruct.GPIO_Mode = gpio_cfg[index].mode;
		GPIO_InitStruct.GPIO_Speed = gpio_cfg[index].speed;

		GPIO_Init(gpio_cfg[index].port, &GPIO_InitStruct);

		if (gpio_cfg[index].mode == GPIO_Mode_Out_OD || gpio_cfg[index].mode == GPIO_Mode_Out_PP)
		{
			if (gpio_cfg[index].val_init)
				GPIO_SetBits(gpio_cfg[index].port, gpio_cfg[index].pin);
			else
				GPIO_ResetBits(gpio_cfg[index].port, gpio_cfg[index].pin);
		}
	}

	o_led1.dis();
	o_led2.dis();
}

/*******************************************************************************
 * @brief  bsp_gpio
 * \param[in] us delay
 * \retval: none
 *******************************************************************************/

/*******************************************************************************
 * @brief  bsp_gpio
 * \param[in] us delay
 * \retval: none
 *******************************************************************************/
void bsp_gpio_mode_out_pp(GPIO_TypeDef *port, uint8_t pin)
{
	intx_alloc();

	intx_disable();

	multi32_bits4_set(port->CFGLR, pin, 1UL);

	intx_enable();
}

void bsp_gpio_mode_out_od(GPIO_TypeDef *port, uint8_t pin)
{
	intx_alloc();

	intx_disable();

	multi32_bits4_set(port->CFGLR, pin, 5UL);

	intx_enable();
}
/*******************************************************************************
 * @brief:
 * @param *port
 * @param pin
 * @param spd [1,2,3]
 * @return {*}
 ******************************************************************************/
void bsp_gpio_mode_out_pp_spd(GPIO_TypeDef *port, uint8_t pin, uint32_t spd)
{
	intx_alloc();

	intx_disable();

	multi32_bits4_set(port->CFGLR, pin, spd | 0x00);

	intx_enable();
}
/*******************************************************************************
 * @brief:
 * @param *port
 * @param pin
 * @param spd [1,2,3]
 * @return {*}
 ******************************************************************************/
void bsp_gpio_mode_out_od_spd(GPIO_TypeDef *port, uint8_t pin, uint32_t spd)
{
	intx_alloc();

	intx_disable();

	multi32_bits4_set(port->CFGLR, pin, spd | 0x04);

	intx_enable();
}

void bsp_gpio_mode_in_up(GPIO_TypeDef *port, uint8_t pin)
{
	intx_alloc();

	intx_disable();

	multi32_bits4_set(port->CFGLR, pin, 8UL);
	port->BCR = 1UL << pin;

	intx_enable();
}

void bsp_gpio_mode_in_dn(GPIO_TypeDef *port, uint8_t pin)
{
	intx_alloc();

	intx_disable();

	multi32_bits4_set(port->CFGLR, pin, 8UL);
	port->BSHR = 1UL << pin;

	intx_enable();
}

void bsp_gpio_mode_in_ft(GPIO_TypeDef *port, uint8_t pin)
{
	intx_alloc();

	intx_disable();

	multi32_bits4_set(port->CFGLR, pin, 4UL);

	intx_enable();
}

void bsp_gpio_mode_ain(GPIO_TypeDef *port, uint8_t pin)
{
	intx_alloc();

	intx_disable();

	multi32_bits4_set(port->CFGLR, pin, 0UL);

	intx_enable();
}

void bsp_gpio_mode_set(GPIO_TypeDef *port, uint8_t pin, char pm)
{
	switch (pm)
	{
	case PIN_MODE_IN_UP:
	{
		bsp_gpio_mode_in_up(port, pin);
		break;
	}
	case PIN_MODE_IN_DN:
	{
		bsp_gpio_mode_in_dn(port, pin);
		break;
	}
	case PIN_MODE_IN_FLOAT:
	{
		bsp_gpio_mode_in_ft(port, pin);
		break;
	}
	case PIN_MODE_IN_AIN:
	{
		bsp_gpio_mode_ain(port, pin);
		break;
	};
	case PIN_MODE_OUT_SL_PP:
	{
		bsp_gpio_mode_out_pp_spd(port, pin, 2);
		break;
	}
	case PIN_MODE_OUT_SL_OD:
	{
		bsp_gpio_mode_out_od_spd(port, pin, 2);
		break;
	}
	case PIN_MODE_OUT_SM_PP:
	{
		bsp_gpio_mode_out_pp_spd(port, pin, 1);
		break;
	}
	case PIN_MODE_OUT_SM_OD:
	{
		bsp_gpio_mode_out_od_spd(port, pin, 1);
		break;
	}
	case PIN_MODE_OUT_SH_PP:
	{
		bsp_gpio_mode_out_pp_spd(port, pin, 3);
		break;
	}
	case PIN_MODE_OUT_SH_OD:
	{
		bsp_gpio_mode_out_od_spd(port, pin, 3);
		break;
	}
	default:
	{
		break;
	}
	}
}

/*******************************************************************************
 * @brief  ext sim io
 *******************************************************************************/
uint8_t ext_io_out_get(char gp)
{
	uint8_t val = 0;

#define EXT_IO_OUT_BIT(n)    \
	if (ext_port_out[gp][n]) \
		val |= BIT(n);

	EXT_IO_OUT_BIT(0);
	EXT_IO_OUT_BIT(1);
	EXT_IO_OUT_BIT(2);
	EXT_IO_OUT_BIT(3);
	EXT_IO_OUT_BIT(4);
	EXT_IO_OUT_BIT(5);
	EXT_IO_OUT_BIT(6);
	EXT_IO_OUT_BIT(7);

	return val;
}
